package com.sunfeng.n4.reentrant;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 条件变量
 *
 * @author sunfeng
 * @date 2021/03/30 14:06
 **/

@Slf4j(topic = "c.ReentrantLockTest4")
public class ReentrantLockTest4 {
    private static ReentrantLock reentrantLock = new ReentrantLock();
    private static Condition oneCondition = reentrantLock.newCondition();
    private static Condition twoCondition = reentrantLock.newCondition();
    private static boolean one = false;
    private static boolean two = false;

    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(() -> {
            reentrantLock.lock();
            try {
                while (!one) {
                    try {
                        log.debug("one,条件不满足 进入等待附列");
                        oneCondition.await();
                        log.debug("one,条件满足 出等待附列");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("可以开始干活了");

            } finally {
                reentrantLock.unlock();
            }

        }, "t1");

        thread1.start();


        Thread thread2 = new Thread(() -> {
            reentrantLock.lock();
            try {
                while (!two) {
                    try {
                        log.debug("two,条件不满足 进入等待附列");
                        twoCondition.await();
                        log.debug("two,条件满足 出等待附列");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("可以开始干活了");

            } finally {
                reentrantLock.unlock();
            }

        }, "t2");

        thread2.start();
        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            reentrantLock.lock();
            try {

                one = true;
                oneCondition.signalAll();
            } finally {
                reentrantLock.unlock();
            }
        }).start();
        TimeUnit.SECONDS.sleep(2);

        new Thread(() -> {
            reentrantLock.lock();
            try {

                two = true;
                twoCondition.signalAll();
            }finally {
                reentrantLock.unlock();
            }
        }).start();
    }
}
